iT邦幫忙

2023 iThome 鐵人賽

DAY 8
1

說明

理想的狀態是在開始程式開發之前,首先明確定義專案需求並撰寫相對應的測試案例。接著,我們採用「紅燈/綠燈(Red/Green)」的測試驅動開發(TDD)策略,這樣就能逐步、有計劃地完成專案。對於那些尚未熟悉測試語法或工具的開發者如果來說,初期可能需要投入更多時間來練習,因為養成良好的測試習慣也是開發過程中不可或缺的一環。

值得一提的是,在撰寫測試的過程中,我也常會發現原有程式碼中存在可優化或改進的部分。這不僅有助於提升程式的品質,也能讓整個開發流程更加順暢。

雖然這次的開發過程中,可能無法完全按照標準的TDD方法來執行,但我補充了基本的測試,包括單元測試(unit test)和端到端測試(e2e test)以確保程式的穩定性和可靠性。

測試工具選擇

  • 單元測試:使用 vitest + vue-test-utils
  • 端到端測試:使用 Cypress

單元測試

安裝

npm install --save-dev vitest @vue/test-utils
npm install vitest

測試項目

  • 測試基本渲染:確認標題是否正確顯示。
  • 頁面切換:模擬點擊行為,確認頁面元素。
  • 分數計算:驗證遊戲分數。
  • 分數回饋:根據分數給出不同的回饋文字。

實際操作

import { shallowMount } from "@vue/test-utils";
import { describe, it, expect } from "vitest"
import Playboard from "@/components/Playboard.vue";

describe("Playboard.vue", () => {
    it("renders mounted 顯示標題,測試物件基本渲染", () => {
        const msg = "時間線任務";
        const wrapper = shallowMount(Playboard);
        const title = wrapper.get('[data-test="title"]')
        expect(title.text()).toMatch(msg);
    });

    it("頁面切換",async () => {
        const wrapper = shallowMount(Playboard);
        const btn = wrapper.get('[data-test="game-start-btn"]')
        await btn.trigger('click')
        expect(wrapper.get('[data-test="timeline"]').exists()).toBe(true)
    });

    it("計分", async () => {
        const wrapper = shallowMount(Playboard);
        wrapper.vm.isGameStart = true
        wrapper.vm.gameStatus.scoreRecord = [1, 2, 3, 4, 5]
        wrapper.vm.gameStatus.score = wrapper.vm.getTotalScore()
        await wrapper.vm.$nextTick()
        expect(wrapper.get('[data-test="score"]').text()).include(15)
    });

    it("分數回饋", async () => {
        const wrapper = shallowMount(Playboard);
        wrapper.vm.isGameEnd = true
        const msg = '非常好!你對網頁開發的歷史有著很好的掌握,在這個領域幾乎是專家囉。';
        const comment = wrapper.vm.gameComment(20)
        expect(comment).toBe(msg)
    });
});

端到端測試

安裝

npm install --save-dev cypress

測試項目

  • 使用 Cypress 進行拖曳效果的測試。測試正確與錯誤的拖曳情況。

實際操作

describe('測試在 Mobile 版本下的拖曳功能', () => {
  beforeEach(() => {
    cy.viewport('iphone-6')
  })
  it('正確與錯誤兩種情況產生的作答結果', () => { 
    cy.visit('http://localhost:5173/TimelineQuest-ithelp-sample/')
    cy.get('[data-test="game-start-btn"]').click()
    cy.get('[data-test="timeline"]').should('be.visible')
    cy.get('[data-test="clue-card"]').trigger('touchstart').trigger('touchmove', { which: 1, pageX: 190, pageY: 250 }).trigger('touchend')
    cy.get('[data-test="timeline-event-year-correct"]').should('have.text', '1995').should('have.class', 'bg-[#5cb887]')
    cy.get('[data-test="clue-card"]').trigger('touchstart').trigger('touchmove', { which: 1, pageX: 190, pageY: 450 }).trigger('touchend')
    cy.get('[data-test="timeline-event-year-wrong"]').should('have.text', '2015').should('have.class', 'bg-[#d25353]')
  })
})

不同測試方針總整理

  1. 單元測試(Unit Testing)
  • 測試事件排序功能:確保用戶可以正確地按照時間順序排列事件。
  • 測試用戶界面元素:例如,確保所有按鈕、滑塊等都能正常工作。
  1. 集成測試(Integration Testing)
  • 測試遊戲流程:從遊戲開始到結束,確保所有步驟都能順利執行。
  • 測試數據存儲和讀取:如果有用於保存遊戲狀態或結果的後端服務,確保它們能正確地存儲和讀取數據。
  1. 端到端測試(End-to-End Testing)
  • 測試整個用戶體驗:模擬用戶從訪問網站到完成遊戲的整個過程。
  1. 性能測試
  • 測試負載能力:確保網站能夠在高流量下正常運行。
  • 測試響應時間:確保網站在不同設備和網絡條件下都有良好的響應時間。
  1. 可用性和可訪問性測試
  • 測試在不同瀏覽器和設備上的兼容性。
  • 確保網站符合可訪問性標準,如 WAI-ARIA。
  1. 測試工具和函式庫
  • 單元測試:Jest, Mocha
  • 端到端測試:Cypress, Selenium
  • 性能測試:JMeter, LoadRunner

注:具體的測試計劃會根據您的實際需求和目標而有所不同。

參考資料
如何使用 Vue 和 Jest 測試拖曳和放置
Vitest 功能指南
[Jsdom 設定
TDD 的三大法則
Cypress 官方文件
ChatGPT


上一篇
寫可維護的程式
下一篇
切版 (將 Layout 和 PSD 轉成 HTML)
系列文
打造紐時風格的時間線小遊戲30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言